<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }

        a,a:active,a:hover{
            text-decoration: none;
        }

        ul,ol,li{
            list-style: none;
        }

        img{
            width: 100%;
            height: 100%;
        }

        .clear{
            clear: both;
            content: "";
            display: block;
        }

        .banner{
            width: 800px;
            height: 400px;
            border: solid;
            margin: 40px auto;
            position: relative;
        }

        .banner > ul{
            width: 500%;
            height: 100%;
            position:relative;
        }

        .banner > ul > li{
            width: 800px;
            height: 100%;
            color: #fff;
            display: flex;
            justify-content: center;
            align-items: center;
            float:left;
            font-size: 150px;
        }

        .banner > ol {
            height: 50px;
            padding: 0px 10px ;
            background: rgba(0,0,0,.5);
            position: absolute;
            bottom: 50px;
            left: 50%;
            transform:translateX(-50%) ;
            border-radius: 15px ;
            display: flex;
            justify-content: center;
            align-items: center;
        }

        .banner > ol > li{
            width: 20px;
            height: 20px;
            border-radius: 50%;
            background: #fff;
            margin: 0 15px;
            cursor: pointer;
        }

        .banner > ol > li.active{
            background: red;
        }

        .banner > div{
            width: 100%;
            height: 50px;
            position: absolute;
            left: 0;
            top: 50%;
            transform:translateY(-50%) ;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        .banner > div > a{
            display: flex;
            width: 50px;
            height: 50px;
            font-size: 30px;
            color: #fff;
            background: rgba(0,0,0,.5);
            justify-content: center;
            align-items: center;
        }
    </style>
</head>
<body>
    
    <div class="banner">
        <!-- 实际项目中,图片标签,都是动态生成的 -->
        <ul class="clear"></ul>
        <ol></ol>
        <div>
            <a href="JavaScript:;">&lt;</a>
            <a href="JavaScript:;">&gt;</a>
        </div>
    </div>

    <script src="../../../tools.js"></script>
    <script>
        // 目标轮播图,原始图片,路径信息,应该是 img标签 src的属性值
        var imgArr = [
            { width:1920,height:500,size:127,src:'./images/1.jpg',name:'轮播图1' },
            { width:1920,height:500,size:337,src:'./images/2.jpg',name:'轮播图2' },
            { width:1920,height:500,size:247,src:'./images/3.jpg',name:'轮播图3' },

        ];



        // 获取标签对象:

        // 获取轮播图div标签对象
        const oBanner = document.querySelector('.banner');

        // 获取轮播图div中的ul标签对象
        const oUl = oBanner.querySelector('ul');

        // 获取轮播图div中的ol标签对象
        const oOl = oBanner.querySelector('Ol');


        // 定义变量

        // 存储数组单元格数
        let arrLength = imgArr.length;

        // 获取div宽度或者获取li宽度
        let divWidth = parseInt( myGetStyle( oBanner , 'width' ) );

        // 定义变量,储存 轮播图 轮序播放时 对应的li 的索引下标
        // 起始值 是 原始轮播图的 第一张图片 也就是 当前li中的第二个li 索引下标是 1
        let index = 1;
 
        // 1, 调用函数, 根据数组数据库, 生成 ul和ol中的标签对象
        setLi(imgArr);

        // 2, 调用自动轮播函数,让轮播图,自动轮序播放
        autoLoop();




        // 一, 定义一个函数,根据数组属性,生成 标签字符串,吸入ul,ol
        function setLi(array){
            // 根据数组,生成 字符串标签

            // 存储 生成的ul>li标签对象字符串
            let ulStr = '';
            // 存储 生成的ol>li标签对象字符串
            let olStr = '';

            // 循环遍历数组对象
            array.forEach(function(val,key){
                // ul>li中 标签内容是 li>img>src属性值是数组中存储的路径数据
                ulStr += `
                    <li>
                        <img src="${val.src}">    
                    </li>
                `
                // ol>li中 标签内容是 li标签本身
                // 第一个li标签,也就是索引是0时,拼接的li,添加class样式
                // 其他li标签,没有 class样式
                olStr += key === 0 ?  '<li class="active"></li>' : '<li></li>';
                
            })

            // 将生成的ul>li字符串写入ul标签对象
            oUl.innerHTML = ulStr;
            // 将生成的ol>li字符串写入ol标签对象
            oOl.innerHTML = olStr;

            // 将原始轮播图写入到ul中之后,ul中才有li标签
            // 将原始第一个li,复制克隆,写入到ul标签的末位
            // 将原始最后一个li,复制克隆,写入到ul标签的首位
            
            // 获取ul中所有的li标签对象
            const oOlLis = oUl.querySelectorAll('li'); 

            // 获取第一个li标签对象和最后一个li标签对象
            const oFirst = oOlLis[0];
            const oLast = oOlLis[arrLength-1];

            // 克隆第一个和最后一个标签对象 
            const oFirstClone = oFirst.cloneNode(true);
            const oLastClone = oLast.cloneNode(true);

            // 克隆的第一个标签,写入到ul的最后
            oUl.appendChild( oFirstClone );
            // 克隆的最后一个标签,写入到ul的起始
            oUl.insertBefore( oLastClone ,  oFirst);


            // 设定 oUl的宽度 是 一个li的宽度/div宽度 * li的个数+2
            // 也就是数组中数据单元个数也就是轮播图原始图片个数 + 2张克隆的图片个数
            oUl.style.width = divWidth * (arrLength+2) + 'px';

            // 重新定位 ul 
            // 定位的数值是 负的 index * li/div宽度 拼接 px单位
            oUl.style.left = -index * divWidth + 'px';

            // oUl.style.left = `${-index * divWidth}px`;

        }

        // 2 自动轮播函数
        function autoLoop(){
            // 定义一个定时器
            setInterval(function(){
                // 1, 每次执行定时器,先给 index 执行自增操作
                index++;

                // 2, 调用 move运动函数
                // 运动的标签对象,是 ul 标签
                // 运动的属性和属性值
                //     属性是 left 属性
                //     属性值 负的 index 乘以 一个li/div的宽度
                // 参数3,是定义的 运动结束回调函数的 函数名称
                move(oUl , {left: -index*divWidth} , loopEnd)

            } , 3000)
        }


        // 3, 运动终止时,调用的回调函数
        function loopEnd(){
            // 判断 index 中 存储的数值

            // 如果 index值 是 最后一个li的索引下标
            // 也就是 原始数组的长度 +2 -1 
            if( index === arrLength+2-1 ){
                index = 1;
            }

            // 根据 新的 index 数值 对 ul标签,重新定位
            // 定位是 瞬间改变的 不是调用move运动函数,动画完成的
            oUl.style.left = -index * divWidth + 'px';

            // 调用 设定 焦点按钮 class样式函数
            setFocusStyle()

        }

        // 4, 切换 ol>li 焦点按钮 class样式
        function setFocusStyle(){
            // 获取所有的ol>li标签对象
            // 必须注意,ol>li标签对象,是动态生成的
            // 必须要在写入之后,再获取
            const oOiLis = oOl.querySelectorAll('li');

            // 循环遍历 oOiLis 中所有的 ol>li 标签
            oOiLis.forEach(function(val){
                // 先清除所有ol>li,class中,active属性值
                myDelClass( val , 'active' );
            })

            // 给当前ul>li对应的 ol>li 添加 class,active样式
            // 对应 关系是 ul>li 的索引下标-1 是 ol>li的索引下标
            // 当前 ul>li 多索引下标 也就是 index的数值
            // ol>li的索引下标 就是 index-1
            oOiLis[index-1].className += ' active'
        }



        /* 
            
            轮播图1 HTML css定义

            轮播图2 生成 ul中li和img图片标签 ol中li标签
                2-1 轮播图 原始图片 6张 ul,ol中都是生成6个li 
                    1, 生成 ul>li 和 ol>li 标签对象
                    循环变量 数组 
                            ul>li 内容是: 
                                li标签中嵌套 img标签 
                                img标签 scr 属性值 是 数组中存储的路径信息,实际项目中一般是一个图片的网址

                            ol>li 内容是:
                                第一个li标签,拼接class样式
                                li标签本身

                    2, 将 生成的 ul>li 字符串, 写入 ul标签对象 
                    将 生成的 ol>li 字符串, 写入 ol标签对象
                    
                    3, 设定 动态渲染生成 ul宽度
                        div宽度/li宽度 * 数组中单元个数 + 2
                                        li个数,轮播图原始图片个数 + 两个克隆的图片个数

        
            轮播图3 自动轮播
                1, 本质:
                    所谓的轮播运动,本质是改变 标签ul 定位属性left 的属性值
                    属性值的改变,不是 直接完成的 是通过 运动函数 完成的动画效果

                    move( 运动的标签对象 , 运动的属性和属性值 , 运动结束执行的回调函数 )
                        运动的标签对象是 ul标签

                        运动的属性和属性值 运动的属性是 定位的left 属性
                                         属性值是 显示的li标签,索引下标 * 一个li/一个div 的宽度

                        运动结束执行的回调函数 是 后面定义的 loopEnd 函数
                                                赋值时 要 赋值 函数名称

                    定义一个变量,变量储存 轮播时 循环到 那个li的索引下标
                    起始 时 显示的是 原始轮播图,第一张图片,但是 是 现在 所有li中的 第二个li 索引下标是 1

                    通过定时器 每间隔一段时间 给 变量index++
                    定位的 属性值 就是   负的 index * li/div宽度 
                                        -index * divWidth 

                2, 关键变量index 
                    index变量中 存储的数值 本质是 索引下标
                    是 当前显示的 li标签的对应的 索引下标
                    显示的li标签 是通过 调整 ul定位 实现的
                    索引下标也就是对应的 定位left 的数值 
                    定位left的数值 本质上 是 -li的索引下标 * 一个li/div的宽度

                    轮播图中,使用index变量储存的数值,控制 ul定位 也就是 控制 轮播图显示的图片
        
        
        
            轮播图4: 运动停止,回调函数

                1, 显示图片的切换  也就是 ul定位的改变 也就是 index的改变
                    如果 index 是 最后一个li的索引下标 
                        运动结束也就是 ul定位结束 也就是显示图片切换结束
                            ul定位 应该是 第二个li的定位 
                            也就是 index 要 赋值 初始状态的 1
                            给 ul 重新定位 定位数值还是 -index * 一个li/div的宽度
                            这个 切换回 第二个li显示 需要瞬间完成 不要运动完成
                            直接定位,不是调用 运动函数

                2, 切换 焦点li--ol>li 标签样式
                    方法和思路 和 tab切换/选项卡类似
                    清除 所有 ol>li 标签 class,active样式
                    根据 当前 显示li的索引下标 也就是 index变量中存储的 数值
                    找到 对应的 ol>li 标签 添加 class,active 样式
                    对应关系 ul>li的索引下标 -1  对应  ol>li 索引下标


        
        */
    </script>
</body>
</html>